#ifndef MAINWINDOW_H
    #include "mainwindow.h"
#endif

extern void Log(const char* format, ...);

DWORD GetTickCount()
{
    return (DWORD)time(0);
}

nThread::nThread()
{

}

nThread::~nThread()
{

}

void nThread::socketDisconnected()
{
    Log("Disconnected");
}

int nThread::OnData(char* data, int size)
{
    if(size < 2) return 0;

    tPacket* packet = (tPacket*)data;
    int processed = 0;
    bool encrypted = false;

    // Encrypted
    if(packet->size & 0x8000)
    {
        encrypted = true;

        int realSize = packet->size & 0x7FFF;
        int bfSize = PacketProcessor->HandShakeApi.blowfish.GetOutputLength(realSize + 4);
        if((bfSize + 2) > size) return 0;

        PacketProcessor->HandShakeApi.blowfish.Decode((BYTE*)data + 2, (BYTE*)data + 2, bfSize);
        processed = (bfSize + 2);
        packet->size &= 0x7FFF;
    }
    //Not encrypted
    else
    {
        if((packet->size + 6) > size)
            return 0;

        processed = (packet->size + 6);
    }

    // Forward the packet to the packet processor
    PacketProcessor->OnPacket(packet, false);

    return processed;
}

void nThread::run()
{
    // Create a new socket
    sSocket = new QTcpSocket(this);

    // Create a new packet processor
    PacketProcessor = new PacketProcessorz(sSocket);

    // Set the receive index
    recvIndex = 0;

    // Connect the read event to a slot
    connect(sSocket, SIGNAL(readyRead()), this, SLOT(readData()));

    // Disconnected
    connect(sSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));

    // Random seed
    srand(GetTickCount());

    // Random server
    switch(rand() % 4)
    {
    case 0:
        sSocket->connectToHost("121.128.133.26", 15779);
        break;
    case 1:
        sSocket->connectToHost("121.128.133.27", 15779);
        break;
    case 2:
        sSocket->connectToHost("121.128.133.28", 15779);
        break;
    case 3:
        sSocket->connectToHost("121.128.133.29", 15779);
        break;
    case 4:
        sSocket->connectToHost("121.128.133.30", 15779);
        break;
    default:
        sSocket->connectToHost("121.128.133.26", 15779);
    }

    // Create a new timer
    timer1 = new QTimer(this);

    // Connect the timer with the slot
    connect(timer1, SIGNAL(timeout()), this, SLOT(Timer()));

    // Execute the timer (1 second)
    timer1->start(1000);

    // Process thread events
    exec();
}

void nThread::Timer()
{
    // Send the notification to the packet processor
    PacketProcessor->OnTimer();
}

void nThread::readData()
{
    QDataStream in(sSocket);
    in.setVersion(QDataStream::Qt_4_6);

    // Get the number of bytes available
    int bytesAvailable = sSocket->bytesAvailable();

    // Read data
    in.readRawData(recvBuffer + recvIndex, 8192 - recvIndex);

    // Processing data
    int bytesProcesed = 0;
    recvIndex += bytesAvailable;

    do
    {
        bytesProcesed = OnData(recvBuffer, recvIndex);

        if(bytesProcesed == 0)
        {
        }
        else if(bytesProcesed == recvIndex)
        {
            recvIndex = 0;
        }
        else
        {
            memmove(recvBuffer, recvBuffer + bytesProcesed, recvIndex - bytesProcesed);
            recvIndex -= bytesProcesed;
        }
    }
    while(bytesProcesed && recvIndex);
}
